//
// Copyright © 2021 dev. All rights reserved.
// 

import Cocoa
import Combine
import os.log

final class WWDCAgentClient:NSObject, ObservableObject {
  private  let log = OSLog(subsystem: "io.wwdc.app.AgentClient", category: String(describing: WWDCAgentClient.self))
    static let allEventsToken = "(All Events)"

    @Published private(set) var isConnected = false
    @Published private(set)  var searchResults:[String] = []
    @Published  var filterEventId:String = WWDCAgentClient.allEventsToken

    private var eventId:String? {filterEventId == Self.allEventsToken ? nil :filterEventId}
    @Published  var searchTerm:String = ""


    var isAgentPreferenceEnabled:Bool {
        guard let defaults = UserDefaults(suiteName: "io.wwdc.app") else { return false }
        return defaults.bool(forKey: "isAgentEnabled")
    }
    private var cancelables = Set<AnyCancellable>()

private var resumed = false

    private var agent:WWDCAgentInterface? {
        return connection.remoteObjectProxyWithErrorHandler { [weak self] error in
            DispatchQueue.main.async {
                self?.isConnected = false
            }
        } as? WWDCAgentInterface
    }
    override init() {
        super.init()
        os_log("Agent enabled preference is currently set to %{public}@",log:self.log,type:.debug,String(describing: isAgentPreferenceEnabled))
        DistributedNotificationCenter.default().addObserver(self, selector: #selector(preferenceChanged(_:)), name: NSNotification.Name("io.wwdc.app.AgentEnabledPreferenceChanged"), object: nil,suspensionBehavior: .deliverImmediately)
    }

    @objc func preferenceChanged(_ note:Notification)  {
     os_log("Agent enabled preference changed to %{public}@", log: self.log, type: .debug, String(describing: isAgentPreferenceEnabled))
    }
    private lazy var connection:NSXPCConnection = {
        let c = NSXPCConnection(machServiceName: "io.wwdc.app.WWDCAgent", options: [])
        c.invalidationHandler = {[weak self] in
            DispatchQueue.main.async {
                self?.isConnected = false
            }
        }

        c.interruptionHandler = {[weak self] in
            DispatchQueue.main.async {
                self?.isConnected = false
            }
        }
        c.remoteObjectInterface = NSXPCInterface(with: WWDCAgentInterface.self)

        return c
    }()

    func connect(){
        guard !resumed else {
            return
        }
        resumed = true
        connection.resume()
        isConnected = true
    }

    func sendTestRequest(with completion:@escaping (Bool)->Void)  {
        agent?.testAgentConnection(with: { result in
            DispatchQueue.main.async {
                completion(result)
            }
        })
    }

}
